package edu.mtu.citizenscience.ethnography.database;

import java.util.Date;

/**
 * A "model" class used for records pertaining to individual interviews.
 * Note that while the fields of both "Name" properties may be {@code null}, the
 * properties themselves will never be {@code null}.
 * 
 * @author Nicholas Blecha
 */
public final class Interview {
	private static final String EMPTY_STRING = "";
	
	private int ID;
	private String storyTitle;
	private Name subjectName;
	private Name interviewerName;
	private String locationName;
	private Date date;
	private String notes;
	private String mediaPath;
	private boolean uploaded;
	private int serverKey;
	private InterviewFileStatus mediaFolderStatus;
	private InterviewFileStatus audioFolderStatus;
	private InterviewFileStatus photoFolderStatus;
	private boolean isModified = false;
	
	Interview()
	{
		this(0, EMPTY_STRING, new Name(), new Name(), EMPTY_STRING, null, EMPTY_STRING, EMPTY_STRING, false);
	}
	
	Interview(int ID, String title, Name subjectName, Name interviewerName, String locationName,
						Date date, String notes, String mediaPath, boolean uploaded) {
		this.storyTitle = title;
		this.ID = ID;
		this.subjectName = subjectName;
		this.interviewerName = interviewerName;
		this.locationName = locationName;
		this.date = date;
		this.notes = notes;
		this.mediaPath = mediaPath;
		this.uploaded = uploaded;
		mediaFolderStatus = InterviewFileStatus.FOUND;
		audioFolderStatus = InterviewFileStatus.FOUND;
		photoFolderStatus = InterviewFileStatus.FOUND;
	}
	
	public final int getID() {
		return ID;
	}
	final void setID(int iD) {
		ID = iD;
	}
	public final Name getSubjectName() {
		return subjectName;
	}
	public final void setSubjectName(Name subjectName) {
		Name name = subjectName;
		if (subjectName == null) {
			name = new Name();
		}
		if (!(this.subjectName != null && this.subjectName.equals(subjectName))) {
			isModified = true;
		}
		this.subjectName = name;
	}
	public final Name getInterviewerName() {
		return interviewerName;
	}
	public final void setInterviewerName(Name interviewerName) {
		Name name = interviewerName;
		if (interviewerName == null) {
			name = new Name();
		}
		this.interviewerName = name;
	}
	public final String getLocationName() {
		return locationName;
	}
	public final void setLocationName(String locationName) {
		this.locationName = (locationName == null) ? EMPTY_STRING : locationName;
	}
	public final Date getDate() {
		return date;
	}
	public final void setDate(Date date) {
		if (!(this.date != null && this.date.equals(date))) {
			isModified = true;
		}
		this.date = date;
	}
	public final String getNotes() {
		return notes;
	}
	public final void setNotes(String notes) {
		this.notes = (notes == null) ? EMPTY_STRING : notes;
	}
	final String getMediaPath() {
		return mediaPath;
	}
	final void setMediaPath(String mediaPath) {
		this.mediaPath = (mediaPath == null) ? EMPTY_STRING : mediaPath;
	}

	public final boolean isUploaded() {
		return uploaded;
	}

	public final void setUploaded(boolean uploaded) {
		this.uploaded = uploaded;
	}
	
	public static class Name implements Comparable<Name> {
		private String firstName;
		private String lastName;
		
		public Name() {
			this(EMPTY_STRING, EMPTY_STRING);
		}
		
		public Name(String firstName, String lastName) {
			setFirstName(firstName);
			setLastName(lastName);
		}
		
		public String getFirstName() {
			return firstName;
		}
		
		public void setFirstName(String firstName) {
			this.firstName = (firstName == null) ? EMPTY_STRING : firstName;
		}
		
		public String getLastName() {
			return lastName;
		}
		
		public void setLastName(String lastName) {
			this.lastName = (lastName == null) ? EMPTY_STRING : lastName;
		}
		
		public String getReversedFullName() {
			String toReturn = new String(lastName);
			if (!(lastName.equals(EMPTY_STRING) || firstName.equals(EMPTY_STRING))) {
				toReturn += ", ";
			}
			toReturn += firstName;
			return toReturn;
		}
		
		public String getFullName() {
			String toReturn = new String(firstName);
			if (!(firstName.equals(EMPTY_STRING) || lastName.equals(EMPTY_STRING))) {
				toReturn += " ";
			}
			toReturn += lastName;
			return toReturn;
		}

		@Override
		public int compareTo(Name another) {
			int result = this.lastName.compareTo(another.lastName);
			if (result == 0) {
				result = this.firstName.compareTo(another.firstName);
			}
			return result;
		}
	}

	@Deprecated
	final void setMediaFolderStatus(InterviewFileStatus mediaFolderStatus) {
		this.mediaFolderStatus = mediaFolderStatus;
	}

	final void setAudioFolderStatus(InterviewFileStatus audioFolderStatus) {
		this.audioFolderStatus = audioFolderStatus;
	}

	final void setPhotoFolderStatus(InterviewFileStatus photoFolderStatus) {
		this.photoFolderStatus = photoFolderStatus;
	}

	@Deprecated
	public final InterviewFileStatus getMediaFolderStatus() {
		return mediaFolderStatus;
	}

	public final InterviewFileStatus getAudioFolderStatus() {
		return audioFolderStatus;
	}

	public final InterviewFileStatus getPhotoFolderStatus() {
		return photoFolderStatus;
	}

	/**
	 * Returns whether date and subject name have changed from what their original
	 * values. The original value is either what was passed in the constructor, if
	 * the parameterized constructor was used, the first value passed to setDate or
	 * setSubjectName if the default constructor was used, or the value at the time
	 * of the last call to resetModified.
	 * @return {@code true} if the date and subject names have been changed, {@code false}
	 * otherwise
	 */
	final boolean isModified() {
		return isModified;
	}
	
	/**
	 * Resets the "original" values of the date and subject name to whatever is currently
	 * stored there.
	 */
	final void resetModified() {
		isModified = false;
	}
	
	public final void setStoryTitle(String title) {
		String newTitle = (title != null) ? title : "";
		if (!(this.storyTitle != null && this.storyTitle.equals(newTitle))) {
			isModified = true;
		}
		this.storyTitle = newTitle;
	}
	
	public final String getStoryTitle() {
		return storyTitle;
	}
	
	public final int getServerKey() {
		return serverKey;
	}
	
	public final void setServerKey(int serverKey) {
		this.serverKey = serverKey;
	}
}
